﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
using System.Runtime.Serialization.Formatters.Binary;
using System.Drawing.Drawing2D;
using MessagingToolkit.QRCode.Codec;
using MessagingToolkit.QRCode.Codec.Data;
using System.Drawing.Text;
using System.Drawing.Imaging;


namespace Light.Utility
{
    /// <summary>
    /// 图片处理类
    /// </summary>
    public class ImageHelper
    {

        /// <summary>
        /// 将Image转换为byte[]
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        public static byte[] GetBytesFromImage(Image image)
        {
            FileStream fs = new FileStream("imagetemp", FileMode.Create, System.IO.FileAccess.Write, FileShare.None);
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(fs, (object)image);
            fs.Close();
            fs = new FileStream("imagetemp", FileMode.Open, System.IO.FileAccess.Read, FileShare.None);
            byte[] bytes = new byte[fs.Length];
            fs.Read(bytes, 0, (int)fs.Length);
            fs.Close();
            return bytes;
        }


        /// <summary>
        /// 从文件中获取字节流
        /// </summary>
        /// <param name="imagePath">文件路径</param>
        /// <returns>字节数组</returns>
        public static byte[] GetBytesFromFile(string imagePath)
        {
            try
            {
                FileStream fs = File.OpenRead(imagePath);
                byte[] bImage = new byte[fs.Length];
                fs.Read(bImage, 0, bImage.Length);
                fs.Close();
                return bImage;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 将字节数组转换为图片
        /// </summary>
        /// <param name="imageBytes">文件字节数组</param>
        /// <returns>图片</returns>
        public static Image GetImageFromBytes(byte[] imageBytes)
        {
            try
            {
                MemoryStream imageStream = new MemoryStream(imageBytes, true);
                imageStream.Write(imageBytes, 0, imageBytes.Length);
                Image img = Image.FromStream(imageStream);
                imageStream.Flush();
                imageStream.Close();
                imageStream.Dispose();
                return img;
            }
            catch
            {
                return null;
            }
        }

        public static bool SaveImageFromBase64String(string base64String, string fileName)
        {
            try
            {
                Image image = Base64ToImage(base64String);
                image.Save(fileName);

                return true;
            }
            catch (Exception ex)
            {
                //throw ex;
                return false;
            }
        }

        public static Image GetImageFromBase64String(string str)
        {
            byte[] datas = null;
            try
            {
                datas = Convert.FromBase64String(str);
            }
            catch (Exception ex)
            {
                throw new Exception("GetImageFromBase64String Failed:" + ex.Message);
            }

            return GetImageFromBytes(datas);
        }

        /// <summary>
        /// 从路径中获取图片
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static Image GetImageFrom(string path)
        {
            if (File.Exists(path))
            {
                return Image.FromFile(path);
            }
            else
            {
                return null;
            }
        }

        public static string ImageToBase64(Image image)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            MemoryStream stream = new MemoryStream();

            formatter.Serialize(stream, image);
            Byte[] bytes = stream.GetBuffer();

            return Convert.ToBase64String(bytes);
        }

        public static Image Base64ToImage(string base64Str)
        {

            byte[] bytes = Convert.FromBase64String(base64Str);
            Image image = GetImageFromBytes(bytes);

            return Resize(image, image.Width, image.Height);
        }


        /// <summary>
        /// 图片袪色
        /// </summary>
        /// <param name="img"></param>
        /// <returns></returns>
        public static Bitmap DisColor(Bitmap img)
        {
            int height = img.Height;
            int width = img.Width;

            Bitmap newMap = new Bitmap(width, height);
            Bitmap originalMap = img;
            Color originalColor;
            for (int w = 0; w < width; w++)
            {
                for (int h = 0; h < height; h++)
                {
                    originalColor = originalMap.GetPixel(w, h);
                    int r, g, b, result = 0;
                    r = originalColor.R;
                    g = originalColor.G;
                    b = originalColor.B;
                    result = (int)(0.7 * r) + (int)(0.2 * g) + (int)(0.1 * b);
                    newMap.SetPixel(w, h, Color.FromArgb(result, result, result));
                }
            }
            return newMap;

        }

        #region 添加水印

        /// <summary>
        /// 加水印文字
        /// </summary>
        /// <param name="img">图片</param>
        /// <param name="words">文字</param>
        /// <param name="font">字体</param>
        /// <param name="brush">画笔</param>
        /// <param name="location">位置</param>
        /// <returns></returns>
        public static Image WaterMark(Image img, string words, Font font, Brush brush, Point location)
        {
            Graphics drawBord = Graphics.FromImage(img);
            drawBord.DrawString(words, font, brush, location);
            return img;
        }

        /// <summary>
        /// 加水印文字
        /// </summary>
        /// <param name="img">图片</param>
        /// <param name="words">文字</param>
        /// <param name="font">字体</param>
        /// <param name="color">颜色</param>
        /// <param name="x">当angel为0时，表示起点X坐标,否则表示旋转点X坐标</param>
        /// <param name="y">当angel为0时，表示起点Y坐标,否则表示旋转点Y坐标</param>
        /// <param name="angle">旋转角度</param>
        /// <returns></returns>
        public static Image WaterMark(Image img, string words, Font font, Color color, int x, int y, float angle)
        {
            if (img == null || String.IsNullOrEmpty(words) || x >= img.Width || y >= img.Height)
                return img;

            if (x > img.Width)
                x = 0;
            if (y > img.Height)
                y = 0;

            Brush brush = new SolidBrush(color);
            Point location = new Point(x, y);

            Graphics g = Graphics.FromImage(img);
            SizeF size = g.MeasureString(words, font);
            if (angle > 0)
            {
                GraphicsText graphicsText = new GraphicsText(g);

                // 绘制围绕点旋转的文本
                StringFormat format = new StringFormat();
                format.Alignment = StringAlignment.Center;
                format.LineAlignment = StringAlignment.Center;

                graphicsText.DrawString(words, font, brush
                    , location
                    , format
                    , angle);
            }
            else
            {
                g.DrawString(words, font, brush, location);
            }
            g.Dispose();

            return img;
        }

        #endregion

        #region 生成二维码

        /// <summary>
        /// 生成二维码
        /// </summary>
        /// <param name="content">二维码内容</param>
        /// <param name="scale">尺寸</param>
        /// <param name="imageLogoPath">logo图片路径</param>
        /// <param name="words">水印文字</param>
        /// <returns></returns>
        public static Image QRCodeEncode(string content, int scale, string imageLogoPath, string words)
        {
            return QRCodeEncode(content, scale, imageLogoPath, words, Color.White, Color.Black);
        }

        /// <summary>
        /// 生成二维码
        /// </summary>
        /// <param name="content">二维码内容</param>
        /// <param name="scale">尺寸</param>
        /// <param name="imageLogoPath">logo图片路径</param>
        /// <param name="words">水印文字</param>
        /// <param name="backgroundColor">背景色</param>
        /// <param name="foregroundColor">前景色</param>
        /// <returns></returns>
        public static Image QRCodeEncode(string content, int scale, string imageLogoPath, string words, Color backgroundColor, Color foregroundColor)
        {
            QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
            qrCodeEncoder.QRCodeBackgroundColor = backgroundColor; //背景色
            qrCodeEncoder.QRCodeForegroundColor = foregroundColor;    //前景色
            //qrCodeEncoder.CharacterSet = CharacterSets[cboCharacterSet.Text]; //编码
            qrCodeEncoder.QRCodeScale = scale;

            Bitmap imageCode = qrCodeEncoder.Encode(content);

            if (!String.IsNullOrEmpty(imageLogoPath))
            {
                return Combine(imageCode, imageLogoPath, words);
            }
            return imageCode;
        }


        /// <summary>
        /// 二维码解码
        /// </summary>
        /// <param name="imageCode"></param>
        /// <returns></returns>
        public static string QRCodeDecode(Image imageCode)
        {

            if (imageCode == null)
            {
                return string.Empty;
            }

            QRCodeDecoder qrCodeEncoder = new QRCodeDecoder();
            return qrCodeEncoder.Decode(new QRCodeBitmapImage(new Bitmap(imageCode)));
        }

#endregion
        /// <summary>
        /// 合并图片
        /// </summary>
        /// <param name="imageCode"></param>
        /// <param name="imageLogoPath"></param>
        /// <returns></returns>
        public static Image Combine(Image imageCode, string imageLogoPath)
        {
            return Combine(imageCode, imageLogoPath, null);
        }

        /// <summary>  
        /// 合并图片
        /// </summary>  
        /// <param name="imageCode">二维码图片</param>  
        /// <param name="imageLogoPath">Logo图片路径</param>  
        /// <param name="words">水印文字</param>
        public static Image Combine(Image imageCode, string imageLogoPath, string words)
        {
            Image imageLogo = Image.FromFile(imageLogoPath);        //照片图片    
            if (imageLogo.Height != 65 || imageLogo.Width != 65)
            {
                imageLogo = Resize(imageLogo, 65, 65);
            }
            int borderWidth = 20;
            if (!String.IsNullOrEmpty(words))
                borderWidth = 50;

            Image imageBord = Resize(imageCode, imageCode.Width + borderWidth, imageCode.Height + borderWidth);
            Graphics g = Graphics.FromImage(imageBord);
            g.FillRectangle(Brushes.White, 0f, 0f, imageBord.Width, imageBord.Height);
            g.DrawImage(imageCode, 10, 10, imageCode.Width, imageCode.Height);      //g.DrawImage(imgBack, 0, 0, 相框宽, 相框高);   

            //g.FillRectangle(System.Drawing.Brushes.White, imgBack.Width / 2 - img.Width / 2 - 1, imgBack.Width / 2 - img.Width / 2 - 1,1,1);//相片四周刷一层黑色边框  
            //g.DrawImage(img, 照片与相框的左边距, 照片与相框的上边距, 照片宽, 照片高);  

            int x = imageCode.Width / 2 - imageLogo.Width / 2;
            int y = imageCode.Width / 2 - imageLogo.Width / 2;

            g.DrawImage(imageLogo, x, y, imageLogo.Width, imageLogo.Height);


            if (!String.IsNullOrEmpty(words))
            {
                //添加文字
                //Font font = new System.Drawing.Font("微软雅黑", 30F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                Font font = new System.Drawing.Font("微软雅黑", 20F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));

                x = x - (int)(font.Size * words.Length) / 4;
                g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;

                //g.DrawString(words, font, Brushes.Orange, new Point(x, y + imageLogo.Height));
                g.DrawString(words, font, Brushes.Orange, new Point(x, imageCode.Height + 10));
            }

            g.Dispose();
            return imageBord;
        }

        /// <summary>  
        /// 合并图片
        /// </summary>  
        /// <param name="imageBottom">底图</param>  
        /// <param name="imageTop">顶图</param>  
        /// <param name="x">起点X坐标</param>
        /// <param name="y">起点Y坐标</param>
        public static Image Combine(Image imageBottom, Image imageTop, int x, int y)
        {
            try
            {
                Graphics g = Graphics.FromImage(imageBottom);
                g.DrawImage(imageTop, x, y, imageTop.Width, imageTop.Height);
                g.Dispose();

                return imageBottom;
            }
            catch (Exception ex)
            {

                throw ex;
            }
        }

        /// <summary>  
        /// Resize图片  
        /// </summary>  
        /// <param name="bmp">原始Bitmap</param>  
        /// <param name="destWidth">新的宽度</param>  
        /// <param name="destHeight">新的高度</param>  
        /// <returns>处理以后的图片</returns>  
        public static Image Resize(Image bmp, int destWidth, int destHeight)
        {
            try
            {
                /*
                 * 检查宽高的合法性
                 */
                //如果传0，原图返回
                if (destWidth == 0 && destHeight == 0)
                    return bmp;

                int oldW = bmp.Width;
                int oldH = bmp.Height;

                int newW = 0, newH = 0;

                if (destWidth == 0)
                    destWidth = oldW;
                if (destHeight == 0)
                    destHeight = oldH;

                // 按比例缩放           
                if (oldH > destHeight || oldW > destWidth)
                {
                    if ((oldW * destHeight) > (oldH * destWidth))
                    {
                        newW = destWidth;
                        newH = (destWidth * oldH) / oldW;
                    }
                    else
                    {
                        newH = destHeight;
                        newW = (oldW * destHeight) / oldH;
                    }
                }
                else
                {
                    newW = oldW;
                    newH = oldH;
                }

                Image b = new Bitmap(newW, newH);
                Graphics g = Graphics.FromImage(b);

                // 插值算法的质量  
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.DrawImage(bmp, new Rectangle(0, 0, newW, newH), new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
                g.Dispose();
                return b;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>  
        /// 剪裁
        /// </summary>  
        /// <param name="b">原始Bitmap</param>  
        /// <param name="startX">开始坐标X</param>  
        /// <param name="startY">开始坐标Y</param>  
        /// <param name="destWidth">宽度</param>  
        /// <param name="destHeight">高度</param>  
        /// <returns>剪裁后的Bitmap</returns>  
        public static Image Cut(Image b, int startX, int startY, int destWidth, int destHeight)
        {
            if (b == null)
            {
                return null;
            }
            int oldWidth = b.Width;
            int oldHeight = b.Height;

            if (startX >= oldWidth || startY >= oldHeight)
            {
                return b;
            }
            if (startX + destWidth > oldWidth)
            {
                destWidth = oldWidth - startX;
            }
            if (startY + destHeight > oldHeight)
            {
                destHeight = oldHeight - startY;
            }
            try
            {
                Bitmap bmpOut = new Bitmap(destWidth, destHeight);
                Graphics g = Graphics.FromImage(bmpOut);
                g.DrawImage(b,
                    new Rectangle(0, 0, destWidth, destHeight),
                    new Rectangle(startX, startY, destWidth, destHeight),
                    GraphicsUnit.Pixel);
                g.Dispose();

                return bmpOut;
            }
            catch (Exception ex)
            {
                throw new Exception("图片裁剪失败，" + ex.Message);
            }
        }

        ///// <summary>  
        ///// 剪裁 -- 用GDI+   
        ///// </summary>  
        ///// <param name="b">原始Bitmap</param>  
        ///// <param name="startX">开始坐标X</param>  
        ///// <param name="startY">开始坐标Y</param>  
        ///// <param name="destWidth">宽度</param>  
        ///// <param name="destHeight">高度</param>  
        ///// <returns>剪裁后的Bitmap</returns>  
        //public static Image Cut(Image b, int startX, int startY, int destWidth, int destHeight)
        //{
        //    if (b == null)
        //    {
        //        return null;
        //    }
        //    int oldWidth = b.Width;
        //    int oldHeight = b.Height;

        //    if (startX >= oldWidth || startY >= oldHeight)
        //    {
        //        return b;
        //    }
        //    if (startX + destWidth > oldWidth)
        //    {
        //        destWidth = oldWidth - startX;
        //    }
        //    if (startY + destHeight > oldHeight)
        //    {
        //        destHeight = oldHeight - startY;
        //    }
        //    try
        //    {
        //        Bitmap bmpOut = new Bitmap(destWidth, destHeight);
        //        Graphics g = Graphics.FromImage(bmpOut);
        //        g.DrawImage(b, new Rectangle(0, 0, destWidth, destHeight), new Rectangle(startX, startY, destWidth, destHeight), GraphicsUnit.Pixel);
        //        g.Dispose();

        //        return bmpOut;
        //    }
        //    catch
        //    {
        //        return null;
        //    }
        //}


    }
}
